맨위로가기

절차적 프로그래밍

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

절차적 프로그래밍은 기계어 시대부터 시작된 절차 개념을 기반으로, 명령형 프로그래밍의 한 종류이다. 프로그램의 기능을 수행하는 프로시저(procedure)를 중심으로 구성되며, 모듈성과 코드 재사용성을 높이기 위해 입력(인수), 출력(반환값), 변수 유효 범위 등을 활용한다. 절차적 프로그래밍은 객체 지향, 함수형, 논리 프로그래밍 등 다른 프로그래밍 패러다임과 비교되며, 알골, 포트란, C 언어 등이 대표적인 절차적 프로그래밍 언어에 해당한다.

더 읽어볼만한 페이지

  • 프로그래밍 패러다임 - 지식 표현
    지식 표현은 컴퓨터가 인간의 지식을 이해하고 활용하도록 정보를 구조화하는 기술이며, 표현력과 추론 효율성의 균형, 불확실성 처리 등을 핵심 과제로 다양한 기법과 의미 웹 기술을 활용한다.
  • 프로그래밍 패러다임 - 의도적 프로그래밍
    의도적 프로그래밍은 프로그래머의 의도를 명확히 포착하고 활용하여 소프트웨어 개발 생산성을 향상시키기 위한 프로그래밍 패러다임으로, 트리 기반 저장소를 사용해 코드 의미 구조를 보존하고, WYSIWYG 환경에서 도메인 전문가와 협업하며, 코드 상세 수준 조절 및 자동 문서화를 통해 가독성과 유지보수성을 높이는 데 중점을 둔다.
절차적 프로그래밍
개요
프로그래밍 패러다임명령형 프로그래밍
등장 시기1957년경
영향 받은 것폰 노이만 구조
기계어
영향을 준 것구조적 프로그래밍
모듈러 프로그래밍
특징
설명계산 과정을 순차적인 명령으로 기술하는 프로그래밍 방식
장점이해하기 쉬움
비교적 빠른 실행 속도
단점유지보수 어려움
코드 재사용성 낮음
주요 개념
변수데이터를 저장하는 공간
할당변수에 값을 저장하는 연산
제어 흐름순차
분기
반복
서브루틴특정 작업을 수행하는 코드 블록 (함수, 프로시저)
예시
프로그래밍 언어C
포트란
베이직
파스칼
에이다

2. 역사적 배경

절차('''procedure''')의 개념은 기계어 코드 시대부터 존재했으며, 저수준 언어(어셈블리 언어)의 CALL 명령과 RET 명령이 그 시초이다. 1950년대 중반부터 고수준 언어가 등장하면서 이러한 구조가 계승되었다.

2. 1. 초기 역사

기계어 코드 시대부터 저수준 언어(어셈블리 언어)의 니모닉 코드 CALL 명령과 RET 명령에서 절차(procedure) 개념이 시작되었다. PUSH 명령으로 인수를 스택 메모리에 넣고, 스택 포인터 레지스터를 감소시켜 로컬 변수 영역을 확보하며, 베이스 포인터 레지스터로 인수 및 로컬 변수에 접근하는 스택 프레임 기능 또한 어셈블리 언어에서 유래했다. CALL 명령의 점프 대상 주소에 붙은 레이블은 절차명과 같아졌다. 이러한 구조는 1950년대 중반부터 등장한 고수준 언어에도 이어졌다. 레이블은 형식화된 인수를 갖는 호출명으로 바뀌었고, 스택 프레임 처리는 자동화 및 은폐되어 소스 코드상에서 명확하게 구분되는 절차(프로시저)가 만들어졌다.

3. 주요 특징

크고 복잡한 프로그램을 작성할 때 모듈성은 필수적이다. 절차적 프로그래밍에서 모듈에 대한 입력은 "인수"이며, 출력은 "반환 값"으로, 프로시저에 어떤 형태의 입력과 출력이 이루어지는지 명확한 규칙을 정하여 구현한다.

변수 스코프는 절차의 모듈성을 높이는 기법이다. 절차 내의 변수는 다른 절차에서 접근할 수 없고 (반대도 마찬가지), 동일한 절차의 여러 호출 간에도 유지된다.

절차의 개념은 기계어 코드 시대부터 존재했으며, 저수준 언어(어셈블리 언어)의 니모닉 코드인 CALL 명령과 RET 명령이 그 원점이다. 고수준 언어에서는 레이블이 형식화된 인수를 갖는 호출명으로 변환되었으며, 스택 프레임 처리는 자동화 및 은폐되어 소스 코드상에서 명확하게 구분된 절차로 탄생했다.

3. 1. 모듈성과 유효 범위

모듈성은 프로그램을 독립적인 기능을 수행하는 프로시저 단위로 분할하여 코드의 가독성과 유지보수성을 높이는 것을 의미한다. 프로시저는 어떤 형태의 입력과 출력이 이루어지는지 명확한 규칙을 정하여 구현할 수 있는데, 입력은 주로 '인수'(인자, 매개변수) 형태로, 출력은 '결과값'(반환값)으로 지정한다.

유효범위(스코프)는 변수가 접근 가능한 범위를 제한하는 것으로, 프로시저 간의 불필요한 상호작용을 방지하고 오류 발생 가능성을 줄인다. 즉, 프로시저가 다른 프로시저의 변수에 접근하거나 그 반대의 경우를 막아준다. 명시적인 허가가 없으면 바로 직전 자신의 변수에도 접근할 수 없게 된다. 유효 범위는 서로 다른 장소에서 같은 이름의 변수를 사용하여 혼동되는 것을 막아주고, 다른 프로시저의 영역을 침해하는 것을 막아준다.

모듈성이 덜한 프로시저는 빠르게 만든 간단한 프로그램에서 사용되기도 하는데, 실행환경에서 많은 변수들과 소통하는 경향이 있고, 다른 프로시저가 변수값을 수정할 수도 있게 된다.

더 간단하고, 독립적이고, 다시 사용할 수 있기 때문에 프로시저는 프로그램 라이브러리를 포함하여 서로 다른 사람들이나 단체에서 작성한 코드 조각들을 담을 수 있는 훌륭한 그릇이다.

3. 2. 코드 재사용성

잘 정의된 인터페이스를 가진 프로시저는 코드 재사용을 지원하며, 특히 소프트웨어 라이브러리를 통해 지원한다. 프로시저는 단순하고 자기 완결적이며 재사용 가능한 인터페이스이기 때문에, 여러 사람이 작성한 코드를 조합하고, 라이브러리를 만들 수 있게 해준다.

4. 다른 프로그래밍 패러다임과의 비교

절차적 프로그래밍은 프로그램의 상태를 변경하는 명령문들의 순차적인 실행을 강조하는 명령형 프로그래밍의 일종이다. 절차의 개념은 기계어 코드 시대부터 존재했으며, 어셈블리 언어의 CALL, RET 명령에서 그 기원을 찾을 수 있다. 이러한 구조는 1950년대 중반부터 등장한 고수준 언어에도 그대로 계승되었다.[1]

절차적 프로그래밍은 객체지향 프로그래밍, 함수형 프로그래밍, 논리 프로그래밍 등 다른 패러다임과 비교할 수 있다.


  • 객체지향 프로그래밍(OOP): OOP는 데이터와 코드를 객체로 묶어 프로그램을 구성하는 반면, 절차적 프로그래밍은 자료 구조를 조작하는 절차를 중심으로 구성한다.
  • 함수형 프로그래밍: 순수 함수를 조합하여 프로그램을 작성하며, 함수의 입력과 출력 사이의 관계를 중심으로 구성한다. 반면 절차적 프로그래밍은 상태 변화를 중심으로 프로그램을 구성한다.
  • 논리 프로그래밍: 문제 해결 방법보다는 문제 자체에 초점을 맞춘 선언적 프로그래밍이다. 프롤로그와 같은 논리 프로그래밍 언어는 목표 감소 절차로 프로그램을 취급하여 문제를 해결한다.

4. 1. 명령형 프로그래밍

현재까지 남아있는 대부분의 절차적 프로그래밍 언어는 명령형 프로그래밍 언어이기도 한데, 이것은 실행 환경의 상태를 명시적으로 참조하기 때문이다. 이것은 '변수'(프로세서 레지스터에 대응될 수도 있다)로부터 시작해서 로고 프로그래밍 언어의 "거북이" 위치 같은 것(화면상의 커서부터 시작해서 방바닥 주변에 있는 장치들까지도)까지 어떤 것이든 될 수 있다.

객체지향 프로그래밍과 같이, 일부 명령형 프로그래밍의 형태는 절차적이지 않은 것들도 있다. 절차적 프로그래밍은 실행을 직접 제어한다는 점에서 명령형 프로그래밍으로 분류된다.

절차적 프로그래밍은 명령형 프로그래밍의 하위 분류인데, 절차적 프로그래밍은 블록 (프로그래밍) 및 스코프 (컴퓨터 과학) 개념을 포함하는 반면, 명령형 프로그래밍은 이러한 기능을 필요로 하지 않는 보다 일반적인 개념을 설명하기 때문이다. 절차적 언어는 일반적으로 `if`, `while`, `for`와 같이 블록을 정의하는 예약어를 사용하여 제어 흐름을 구현하는 반면, 비구조적 프로그래밍 명령형 언어(예: 어셈블리 언어)는 이러한 목적으로 goto 및 분기 테이블을 사용한다.

4. 2. 객체지향 프로그래밍

객체지향 프로그래밍(OOP)은 명령형 프로그래밍의 일종으로, 잘 정의된 인터페이스를 통해 동작(메소드)과 데이터(멤버)를 노출하는 객체로 프로그램을 나누어 구현하는 방식이다. 반면, 절차적 프로그래밍은 프로그램 구현을 변수, 자료 구조, 서브루틴으로 나눈다.[3] 중요한 차이점은 절차적 프로그래밍은 자료 구조를 조작하는 절차를 중심으로 프로그램을 구성하는 반면, OOP는 데이터와 코드를 함께 묶어 객체를 중심으로 구성한다는 것이다. 객체는 자료 구조이며, 해당 자료 구조와 관련된 동작이다.[3]

일부 OOP 언어는 정의를 기반으로 객체를 생성할 수 있게 해주는 클래스 개념을 지원한다. 절차적 프로그래밍과 객체 지향 프로그래밍은 명칭은 다르지만 유사한 의미를 가진다.

절차적 프로그래밍객체 지향 프로그래밍
프로시저메소드
레코드객체
모듈클래스
프로시저 호출메시지



C 언어처럼 명확한 모듈 기능을 지원하지 않는 언어도 있다. 반면 객체 지향 프로그래밍에서는 데이터와 코드가 각각 관련성이 높은 것들로 묶여 객체를 이룬다. 클래스 기반 객체 지향 언어에서는 객체의 설계도가 되는 클래스에 필드 (멤버 변수) 및 메서드 (멤버 함수)로 정의된다.

대부분 관련성이 강한 것들을 적극적으로 묶어 명확하게 분류할 수 있는 객체 지향이 응집도가 높아 보수하기 쉽다고 여겨진다. 클래스 기반 객체 지향 언어의 경우, 프로그램은 클래스 집합의 정의로 구성되어 있다. 모든 것을 객체로 간주하는 순수한 객체 지향 언어는 적다. 예를 들어 최초의 객체 지향 언어인 스몰토크가 있지만, 상업적으로 성공했다고는 말하기 어렵다. 널리 사용되는 C++자바처럼, 많은 객체 지향 언어는 절차적 프로그래밍과 객체 지향을 융합한 것이다. 그러한 멀티 패러다임의 객체 지향 언어는, 광의에서는 절차적 언어의 일종으로 분류되기도 한다.[4]

다음은 객체 지향과 절차형 언어 요소를 비교한 표이다.

순수한 객체 지향순수한 절차형
메서드절차(프로시저)
객체구조체(레코드)
클래스모듈
메시지절차 호출


4. 3. 함수형 프로그래밍

함수형 프로그래밍은 순수 함수(부작용이 없는 함수)를 조합하여 프로그램을 작성하는 방식이다. 절차적 프로그래밍은 상태 변화를 중심으로 프로그램을 구성하는 반면, 함수형 프로그래밍은 함수의 입력과 출력 사이의 관계를 중심으로 구성한다. 함수형 프로그래밍 언어는 꼬리 재귀 최적화 및 고차 함수에 의존하는 경향이 있다.

함수형 프로그래밍 언어와 절차적 프로그래밍 언어는 모듈성과 코드 재사용이라는 원칙은 근본적으로 같다. 예를 들어, 프로시저는 함수에 해당하며, 둘 다 프로그램의 다양한 부분과 실행 시점에서 동일한 코드를 재사용할 수 있다. 함수는 함수 인자, 반환 값, 변수 범위를 사용하여 동일한 방식으로 모듈식으로 서로 분리된다.

두 프로그래밍 방식의 주요 차이점은 함수형 프로그래밍 언어가 절차적 프로그래밍의 명령형 요소를 제거하거나 적어도 중요성을 낮춘다는 것이다. 함수형 언어는 순수 함수를 사용하여 프로그램을 작성하도록 설계되었다. 함수형 프로그램은 코드 실행 순서가 자유로울 수 있으며, 언어가 프로그램의 다양한 부분이 실행되는 순서에 대한 제어를 거의 제공하지 않을 수 있다.

함수형 프로그래밍 언어는 일급 함수, 익명 함수, 클로저를 지원하지만, 이러한 개념은 Algol 68 이후부터 절차적 언어에도 포함되어 있다.

많은 함수형 언어는 실제로 순수하지 않은 함수형이며, 프로그래머가 절차적 스타일 또는 두 스타일을 조합하여 프로그램을 작성할 수 있도록 하는 명령형/절차적 구성을 제공한다. 함수형 언어에서 입출력 코드를 절차적 스타일로 작성하는 것이 일반적이다.

하스켈과 같은 순수 함수형 언어는 적고, 스칼라F#처럼 함수형 스타일을 주축으로 하면서 필요에 따라 객체 지향이나 절차형 스타일을 취할 수 있는 멀티 패러다임 언어가 더 많다.

4. 4. 논리 프로그래밍

논리 프로그래밍에서 프로그램은 일련의 전제이며, 후보 정리를 증명하려는 시도를 통해 계산이 수행된다. 이러한 관점에서 논리 프로그램은 문제를 해결하는 방법에 초점을 맞추기보다는 문제 자체가 무엇인지에 초점을 맞춘 선언적 프로그래밍이다.[1]

하지만, SLD 해법에 의해 구현된 후진 추론 기법은 프롤로그와 같은 논리 프로그래밍 언어에서 문제를 해결하기 위해 사용되며, 프로그램을 목표 감소 절차로 취급한다. 따라서 다음과 같은 형태의 절(clause)들은:[1]

:H :- B1, …, Bn.|H :- B1, …, Bn.영어

다음과 같은 두 가지 해석을 가진다.[1]

  • 절차로서: H|H영어를 보여주거나/풀기 위해, B1|B1영어과 … 그리고 Bn|Bn영어을 보여주거나/푼다.[1]
  • 논리적 함축으로서: B1 and … and Bn implies H|B1 and … and Bn implies H영어.[1]


숙련된 논리 프로그래머는 효과적이고 효율적인 프로그램을 작성하기 위해 절차적 해석을 사용하고, 프로그램의 정확성을 보장하기 위해 선언적 해석을 사용한다.[1]

5. 절차적 프로그래밍 언어

절차적 프로그래밍 언어는 절차적 프로그래밍 접근 방식을 따르며, 프로그래머가 작업을 수월하게 할 수 있도록 돕는다. 알골이 대표적인 예시이며, 포트란, PL/I, 모듈라-2, 에이다, 베이직, C 등도 이에 속한다. 이러한 언어들은 절차(프로시저)의 개념을 명확하게 가지고 있으며, 구문으로 정의된다.

C 언어에서 발전한 C++처럼 많은 객체 지향 언어는 절차적 언어의 성질도 계승하고 있어, 객체 지향형 절차적 언어로 분류되기도 한다.

5. 1. 주요 절차적 프로그래밍 언어 목록

알골은 절차적 프로그래밍 언어의 표준적인 예이다. 그 밖에 포트란, PL/I, 모듈라-2, 에이다, 베이직, C 등이 있다. 절차적 프로그래밍으로 간주되는 프로그래밍 언어는 절차(프로시저)의 개념을 명확하게 가지고 있으며, 구문으로 정의하고 있다.

주요 절차적 프로그래밍 언어


5. 2. 객체 지향형 절차적 프로그래밍 언어 목록

C++와 같이 많은 객체 지향 언어는 절차적 언어의 성질도 계승하고 있다. 따라서 객체 지향형 절차적 언어로 분류된다. 대표적인 예시는 다음과 같다.

언어설명
Ada (95 이후)
C++
C#
D 언어
ECMAScript (ActionScript, DMDScript, JavaScript, JScript)
Go
Java
Kotlin
Object Pascal/Delphi
Objective-C
Perl (버전 5 이후)
PHP
Python
Ruby
Rust
Swift
Visual Basic .NET



C++ 등은 클래스에 속하지 않는 톱 레벨(네임스페이스 스코프)의 함수(자유 함수)를 정의할 수도 있는 반면, Java나 C#에서는 메서드는 반드시 어떤 클래스에 속해야 한다. 하지만 호출 시 객체의 인스턴스화를 필요로 하지 않는 `static` 메서드(정적 메서드 또는 클래스 메서드라고도 함)를 정의하여 대용할 수 있으므로, 그러한 차이는 절차형 분류의 결정적인 요인이 되지 않는다.

많은 객체 지향 언어에서는 객체에 대해 `static`이 아닌 메서드(비정적 메서드 또는 인스턴스 메서드라고도 함)를 호출하는 경우, `someInstance.someMethod()`라는 형태의 구문 표기가 채용되고 있지만, 이는 언어 처리계에 따라 메서드의 숨겨진 제0인수에 객체를 `this`로 암묵적으로 전달하는 형태 `SomeClass.someMethod(someInstance)`로 전개된다. 즉, 내부적으로는 절차를 호출하고 있을 뿐이다.

위와 같은 객체 지향의 절차적 언어는 람다식과 같은 함수형 프로그래밍의 기능도 부분적으로 지원하는 것이 일반적이어서, 프로그래밍 패러다임의 분류는 점점 더 모호해지고 있다.

6. 개발 관행

소프트웨어 개발 방식은 절차적 프로그래밍과 함께 소프트웨어 품질 향상 및 개발, 유지 관리 비용 절감을 위해 자주 사용된다.

6. 1. 모듈화 및 범위 지정

모듈화는 프로그램의 절차를 각각 특정한 목적을 가지며 이해하기 쉬운 별도의 모듈로 구성하는 것이다. 변수와 프로시저의 범위를 최소화하면 프로시저와 모듈의 인지 부하를 줄여 소프트웨어 품질을 향상시킬 수 있다.

모듈성이 부족하거나 광범위한 범위를 가진 프로그램은 다른 프로시저도 사용하는 많은 변수를 사용하는 프로시저를 갖는 경향이 있다. 크고 복잡한 프로그램에서는 특히 모듈성이 중요하다. 절차적 프로그래밍에서 모듈에 대한 입력은 구문적으로 "인수"이며, 출력은 "반환 값"이다.

변수 범위는 절차의 모듈성을 높이는 또 다른 기법이다. 절차 내의 변수는 다른 절차에서 접근할 수 없고 (반대도 마찬가지), 동일한 절차의 여러 호출 간에도 유지된다. 범위를 넘어서는 접근에는 특별한 권한이 필요하다.

모듈성이 낮은 절차도 간단한 프로그램에서는 자주 사용된다. 이 경우, 실행 환경 내의 다수의 변수에 접근하고, 다른 절차에서도 마찬가지로 해당 변수에 접근한다.

단순하고 자기 완결적이며 재사용 가능한 인터페이스이기 때문에, 절차를 사용하여 다수의 사람이 작성한 코드를 조합할 수 있게 되었고, 라이브러리 등도 만들 수 있게 되었다.

6. 2. 공유

절차는 명확하게 정의된 인터페이스를 지정하고 자체적으로 포함될 수 있기 때문에 코드 재사용을 지원하며, 특히 소프트웨어 라이브러리를 통해 지원한다.[1]

참조

[1] 웹사이트 Programming Paradigms https://cs.lmu.edu/~[...]
[2] 간행물 Welcome to IEEE Xplore 2.0: Use of procedural programming languages for controlling production systems IEEE
[3] 웹사이트 Procedural programming vs object-oriented programming http://neonbrand.com[...] neonbrand.com 2013-08-19
[4] 웹사이트 手続き型言語(命令型言語)とは - 意味をわかりやすく - IT用語辞典 e-Words https://e-words.jp/w[...]
[5] 웹사이트 関数型プログラミングと命令型プログラミング - LINQ to XML - .NET | Microsoft Learn https://learn.micros[...]
[6] 웹사이트 Pythonってどんな言語? 特徴と歴史を『独習Python』から解説|翔泳社の本 https://www.shoeisha[...]
[7] 웹사이트 値 - F# | Microsoft Learn https://learn.micros[...]



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com